package com.cynteka.cyfoman.core;

import com.cynteka.cyfoman.core.config.ActionQuery;
import com.cynteka.cyfoman.core.config.Folder2DBItem;
import com.cynteka.cyfoman.core.config.Folder2DBItems;
import org.apache.commons.io.DirectoryWalker;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;

/**
 * User: Sergey
 * Date: 25.07.11
 * Time: 13:54
 */
public class Folder2DBSynchronizer extends DirectoryWalker {
    private Logger logger = Logger.getLogger(Folder2DBSynchronizer.class.getName());

    private DataSource dataSource;
    private File baseFolder;
    private String separator = "/"; //File.separator;
    private Folder2DBItems items;
    private int delay = 10000;

    public int getDelay() {
        return delay;
    }

    public void setDelay(int delay) {
        this.delay = delay;
    }

    public Folder2DBItems getItems() {
        return items;
    }

    public void setItems(Folder2DBItems items) {
        this.items = items;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public File getBaseFolder() {
        return baseFolder;
    }

    public void setBaseFolder(File baseFolder) {
        this.baseFolder = baseFolder;
    }

    public String getSeparator() {
        return separator;
    }

    public void setSeparator(String separator) {
        this.separator = separator;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void syncFolders() {
        try {
            walk(baseFolder, null);
        } catch (IOException e) {
            logger.log(Level.SEVERE, "Can not scan folders", e);
        }
    }

    protected boolean handleDirectory(File directory, int depth, Collection results) throws IOException {
        String relName = Util.getRelationName(directory, baseFolder, "/");
        for (Folder2DBItem item : items) {
            Matcher m = item.getPattern().matcher(relName);
            if (m.matches()) {
                List<String> values = Util.getGroups(m);
                for (ActionQuery query : item.getQueries()) {
                    boolean exec = true;
                    JdbcTemplate template = new JdbcTemplate(dataSource);
                    if (query.getCheckSQL() != null) {
                        exec = false;
                        List<String> queryParams = Util.findAllParams(query.getCheckSQL(), values, item.getRegexpVarnames());
                        String sQuery = Util.processQuery(query.getCheckSQL());
                        int n = template.queryForInt(sQuery, queryParams.toArray());
                        exec = n == 0;
                    }
                    if (exec) {
                        List<String> queryParams = Util.findAllParams(query.getSql(), values, item.getRegexpVarnames());
                        String sQuery = Util.processQuery(query.getSql());

                        template.update(sQuery, queryParams.toArray());
                    }
                }
            }
        }
        return true;
    }

    public void startDaemon() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    syncFolders();
                    try {
                        Thread.sleep(delay);
                    } catch (InterruptedException e) {
                        // No problem
                    }
                }
            }
        });
        t.setDaemon(true);
        t.start();
    }
}
